﻿/******************************************************************
 *Company: http://www.xiaomutech.com/
 *fileName : qserialshell.cpp --- QSerialShell
 *Auth       : Niyh  (QQ:393320854)
 *Create    : 2021-11-12
 *Description   :
 *Histroy:
 *<Auth>    <Date>        <Ver>        <Content>
 *         2021/11/12/11/12
 *******************************************************************/
#include "qserialshell.h"

#include <QTextDocument>
#include <QTextCursor>
#include <QTextDocumentFragment>
#include <QDebug>
#include <QKeyEvent>
#include <QApplication>
#include <QClipboard>
#include <QDebug>
#include <QRegExp>

QSerialShell::QSerialShell(QWidget *parent) : QTextEdit(parent)
{
    this->insertedChars = 0;
    this->cursorPosition = 0;
    this->cursor = this->textCursor();
    this->setCursorWidth(3);
    this->setTextCursor(cursor);

    m_serialport = new QSerialPort(this);
    connect(m_serialport, SIGNAL(readyRead()), this, SLOT(slotReadSerial()));
}

QSerialShell::~QSerialShell()
{
    if (m_serialport->isOpen()) {
        m_serialport->close();
    }
}

bool QSerialShell::open(const QString &com, quint32 baudrate)
{
    if (m_serialport->isOpen()) return true;
    m_serialport->setPortName(com);
    if (m_serialport->open(QIODevice::ReadWrite)) {
        m_serialport->setBaudRate(baudrate);
    }

    return m_serialport->isOpen();
}

void QSerialShell::slotReadSerial()
{
    QByteArray byCmd = m_serialport->readAll();

    qDebug() << byCmd << (uchar)byCmd[0];
    if (byCmd.length() == 1){
        uchar temp = (uchar)byCmd[0];
        if (0x07 == temp || 0x08 == temp) return;
    }

    const static QByteArray byTem = QByteArray().append(0x1B).append(0x5B);
    int index = 0;
    if (byCmd.startsWith(QByteArray().append(0x08))) {
        if (1 == byCmd.indexOf(byTem)) {
            this->cursor.deletePreviousChar();
        }
    }

    while ((-1 != (index = byCmd.indexOf(byTem))))
    {
        byCmd.remove(index, 3);
    }

    this->insertPlainText(byCmd);
    this->moveCursor(QTextCursor::End);
}

void QSerialShell::sendCommand(const QString &cmd)
{
    if (m_serialport->isOpen()) {
        m_serialport->write(cmd.toUtf8());
    }
}

void QSerialShell::sendCommand(uchar *data, int len)
{
    if (m_serialport->isOpen()) {
        m_serialport->write((char *)data, len);
    }
}

void QSerialShell::keyPressEvent(QKeyEvent *e)
{
    if (e->modifiers() == Qt::ControlModifier)
    {
        if (e->key() == Qt::Key_C)
        {
            uchar cmd = 0x03;
            sendCommand(&cmd, 1);
        }
        return;
    }

    this->cursor.movePosition(QTextCursor::End);
    this->cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, this->cursorPosition);
    this->setTextCursor(this->cursor);

    if (e->key() == Qt::Key_Return)
    {
        this->cursor.movePosition(QTextCursor::End);
        this->setTextCursor(this->cursor);
        this->cursorPosition = 0;
        this->insertedChars = 0;
        if ("clear" == command) {
            this->clear();
        }

        uchar cmd = 0x0A;
        sendCommand(&cmd, 1);
        this->command.clear();
    }
    else if (e->key() == Qt::Key_Up)
    {
        uchar command[3] = {0x1B, 0x5B, 0x41};
        sendCommand(command, sizeof(command));
    }
    else if (e->key() == Qt::Key_Down)
    {
        uchar command[3] = {0x1B, 0x5B, 0x42};
        sendCommand(command, sizeof(command));
    }
    else if (e->key() == Qt::Key_Left)
    {
        uchar command[3] = {0x1B, 0x5B, 0x43};
        sendCommand(command, sizeof(command));
    }
    else if (e->key() == Qt::Key_Right)
    {
        uchar command[3] = {0x1B, 0x5B, 0x44};
        sendCommand(command, sizeof(command));
    }
    else if (e->key() == Qt::Key_Delete)
    {
        if (this->cursorPosition > 0)
        {
            this->cursor.movePosition(QTextCursor::Right);
            this->setTextCursor(this->cursor);
            this->cursor.deletePreviousChar();
            this->command.remove(this->command.length() - this->cursorPosition - 1, 1);
            this->insertedChars--;
            this->cursorPosition--;
        }
    }
    else if (e->key() == Qt::Key_Backspace)
    {
        if (this->insertedChars > this->cursorPosition)
        {
            this->cursor.deletePreviousChar();
            this->command.remove(this->command.length() - this->cursorPosition - 1, 1);
            this->insertedChars--;
        }

        uchar cmd = 0x08;
        sendCommand(&cmd, 1);
    }
    else if(e->key() == Qt::Key_Escape)
    {

    }
    else if (e->key() == Qt::Key_Tab)
    {
        uchar cmd = 0x09;
        sendCommand(&cmd, 1);
    }
    else if (e->text().length()> 0)
    {
        this->insertedChars++;
        this->command.insert(this->command.length() - this->cursorPosition, e->text());
        sendCommand(e->text());
    }
}
